package procsim;

import java.awt.*;

public class Util {
    public static int[] int2BinaryArray(int in, int num){
        int[] res = new int[num];
        String s=Integer.toBinaryString(in);
        if (s.length()>num){ // ako je broj duzi od ocekivanog, odsecamo nepotrebno
            s=s.substring(s.length()-num, s.length());
            int inx = in; // treba i in onda srediti
            inx >>= num;
            inx <<= num;
            in-=inx;
        }
        else if (num>s.length())
            for(int i=0; i<num-s.length(); i++) // prvo se dopuni nulama, ako ima sta
                res[i]=0;
        for(int i=0; i<s.length(); i++)
            res[i+num-s.length()]=Integer.parseInt(s.substring(i, i+1));
        return reverseIntArray(res);
    }
    public static int binaryArray2Int(int array[]){
        int res=0;
        int[] tmp = reverseIntArray(array);
        for(int i=0; i<tmp.length; i++)
           res+=tmp[tmp.length-1-i]<<i;
        return res;
    }
    public static int[] signalArray2IntArray(Signal s[]){
        int[] res = new int[s.length];
        for(int i=0; i<s.length; i++)
            if (s[i]!=null) res[i]=s[i].get();
            else res[i]=0;
        return res;
    }
    public static Signal[] intArray2SignalArray(int in[]){
        Signal[] res = new Signal[in.length];
        for(int i=0; i<in.length; i++)
            res[i]=new Signal(in[i]);
        return res;
    }
    public static int[] reverseIntArray(int [] in){
        int [] res = new int[in.length];
        for (int i=0; i<in.length; i++)
            res[in.length-1-i]=in[i];
        in=res;
        return in;
    }
    public static int roundToNextMultiple(int num){
        if (Integer.highestOneBit(num)==Integer.lowestOneBit(num))
            return Integer.highestOneBit(num);
        else
            return 2*Integer.highestOneBit(num);
    }
    public static int hex2Int(String str, int numOfBits) throws NumberFormatException {
        // sa Integer.parseInt(str, 16) se ne mogu konvertovati brojevi od 8fffffff do ffffffff
        if(str==null || str.equals("")) throw new NumberFormatException("Empty string!");
        char[] charr=str.toCharArray();
        int ret=0;
        int arrlen=charr.length;
        int availlen=Util.roundToNextMultiple(numOfBits)/4;
        if (arrlen>availlen) throw new NumberFormatException("Hex string too long!");
        for(int i=0; i<arrlen; i++){
            try{
                int cur=Integer.parseInt(""+charr[arrlen-i-1], 16);
                ret+=cur<<i*4; // <<i*4 je bolje od Math.pow(16, i), jer radi za brojeve iznad 8fffffff
            } catch(NumberFormatException nfe){
                throw new NumberFormatException("The entered number is not hexadecimal!");
            }
        }
        return ret;
    }
    public static String int2Hex(int in, int num){
        // sa Integer.toHexString(in); se ne moze postici zeljena preciznost na bajtovima
        if(in==MSignal.HIGHZ) return "HIGHZ";
        int npad=(int)Math.ceil(num/4.);
        return String.format("%0"+npad+"x", in);
    }
    public static String int2HexForMemory(int in, int num){
        // sa Integer.toHexString(in); se ne moze postici zeljena preciznost na bajtovima
        if(in==MSignal.HIGHZ) return "HIGHZ";
        int npad=(int)Math.ceil(num/4.);
        if(npad<4) npad=4;
        return String.format("%0"+npad+"x", in);
    }
    public static boolean toggle(boolean in){
        if(in) return false;
        else return true;
    }
    private static Font font;
    private static Stroke stroke;
    private static Color color;
    public static synchronized void saveGraphics(Graphics2D g){
        font=g.getFont();
        stroke=g.getStroke();
        color=g.getColor();
    }
    public static synchronized void restoreGraphics(Graphics2D g){
        g.setFont(font);
        g.setStroke(stroke);
        g.setColor(color);
    }
}
